/*
 * abuf - Append buffer library
 * author	: calvin
 * email	: calvinwilliams@163.com
 *
 * Licensed under the LGPL v2.1, see the file LICENSE in base directory.
 */

#ifndef _H_ABUF_
#define _H_ABUF_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>

/*
[ABUF_INIT_BUF_SIZE,ABUF_DOUBLE_BUF_SIZE_ON_LESS_THAN] (ABUF_DOUBLE_BUF_SIZE_ON_LESS_THAN,ABUF_MAX_BUF_SIZE]
------------------------------------------------------ -----------------------------------------------------
                   double size                                          increment size
*/

#define ABUF_INIT_BUF_SIZE			16
#define ABUF_DOUBLE_BUF_SIZE_ON_LESS_THAN	1024*1024
#define ABUF_INCREMENT_BUF_SIZE			1024*1024
#define ABUF_MAX_BUF_SIZE			100*1024*1024

struct AppendBuffer *AllocBuffer();
struct AppendBuffer *AllocBufferInitSize( size_t buf_size );
struct AppendBuffer *AllocBufferFromString( char *str );
struct AppendBuffer *AllocBufferFromMemoryBytes( char *mem , size_t len );
void FreeBuffer( struct AppendBuffer *buf );

void ResetAppendBufferFillPtr( struct AppendBuffer *buf );
ssize_t AppendBufferChar( struct AppendBuffer *buf , char ch );
ssize_t AppendBufferString( struct AppendBuffer *buf , char *str );
ssize_t AppendBufferFormatString( struct AppendBuffer *buf , char *format , ... );
ssize_t AppendBufferFormatStringV( struct AppendBuffer *buf , char *format , va_list valist );
ssize_t AppendBufferMemoryBytes( struct AppendBuffer *buf , char *mem , size_t mem_len );
ssize_t OffsetAppendBufferFillPtr( struct AppendBuffer *buf , size_t offset );
ssize_t TryOffsetAppendBufferFillPtr( struct AppendBuffer *buf , size_t offset );

void ResetAppendBufferParsePtr( struct AppendBuffer *buf );
unsigned char CheckAppendBufferParseEnd( struct AppendBuffer *buf );
size_t GetAppendBufferParseInstanceToEnd( struct AppendBuffer *buf );
ssize_t OffsetAppendBufferParsePtr( struct AppendBuffer *buf , size_t offset );

size_t GetAppendBufferSize( struct AppendBuffer *buf );
char *GetAppendBufferBase( struct AppendBuffer *buf );
char *GetAppendBufferFillPtr( struct AppendBuffer *buf );
char *GetAppendBufferParsePtr( struct AppendBuffer *buf );
size_t GetAppendBufferLength( struct AppendBuffer *buf );

size_t *GetAppendBufferSizePtr( struct AppendBuffer *buf );
char **GetAppendBufferBasePtr( struct AppendBuffer *buf );
char **GetAppendBufferFillPtrPtr( struct AppendBuffer *buf );
char **GetAppendBufferParsePtrPtr( struct AppendBuffer *buf );

int ResizeAppendBuffer( struct AppendBuffer *buf , size_t new_buf_size );
int IncrementAppendBuffer( struct AppendBuffer *buf );
int TestAndIncrementAppendBuffer( struct AppendBuffer *buf , size_t add_len );
void CleanAppendBuffer( struct AppendBuffer *buf );

void SetInitBufferSize( struct AppendBuffer *buf , size_t init_buf_size );
void SetDoubleBufferSizeOnLessThan( struct AppendBuffer *buf , size_t double_buf_size_on_less_than );
void SetIncrementBufferSize( struct AppendBuffer *buf , size_t increment_buf_size );
void SetMaxBufferSize( struct AppendBuffer *buf , size_t max_buf_size );

void SetGlobalInitBufferSize( size_t init_buf_size );
void SetGlobalDoubleBufferSizeOnLessThan( size_t double_buf_size_on_less_than );
void SetGlobalIncrementBufferSize( size_t increment_buf_size );
void SetGlobalMaxBufferSize( size_t max_buf_size );

#ifdef __cplusplus
}
#endif

#endif

